﻿
#include "EFrustum.h"

namespace Base3D
{
	//--------------------------------------------------------------------------

	EFrustum::EFrustum(CAMERA_TYPE mode, const EVector4D &pos, const EVector4D &dir,
					const EVector4D& target, EFloat nearZ, EFloat farZ, EFloat ffov, 
					EFloat viewportWidth, EFloat viewportHeight)
					:	camMode(mode), position(pos), direction(dir), camTarget(target),
					clip_z_near(nearZ), clip_z_far(farZ), fov(ffov), 
					viewport_width(viewportWidth), viewport_height(viewportHeight),
					camUp(EVector4D::UNIT_Y),camRight(EVector4D::UNIT_X),camLook(EVector4D::UNIT_Z),
					mWorldToCamera(EMatrix44::IDENTITY), mCameraToPerspective(EMatrix44::IDENTITY),
					mPerspectiveToScreen(EMatrix44::IDENTITY)
	{
		viewport_center_X	= (viewport_width - 1) * 0.5f;
		viewport_center_Y	= (viewport_height - 1) * 0.5f;

		aspect_ratio		= viewport_width / viewport_height;

        view_plane_width		= 2.0f;
        view_plane_height	= 2.0f / aspect_ratio;

		EFloat tan_fov_div2	= tan(Degree_TO_Radian(fov  * 0.5f));
		view_dist			= 0.5f * view_plane_width / tan_fov_div2;

		// 设置裁减平面
		// 裁减平面坐标是基于摄像机坐标系的
		EVector4D	point	= EVector4D::ZERO;
		// 右裁减面
		EVector4D	normalR = EVector4D(-view_dist, 0, view_plane_width * 0.5f);
		clip_plane_R		= EPlane3D(point, normalR);

		// 左裁减面
		EVector4D	normalL = EVector4D(view_dist, 0, view_plane_width * 0.5f);
		clip_plane_L		= EPlane3D(point, normalL);

		// 上裁减面
		EVector4D	normalT = EVector4D(0, -view_dist, view_plane_height * 0.5f);
		clip_plane_T		= EPlane3D(point, normalT);

		// 下裁减面
		EVector4D	normalB = EVector4D(0, view_dist, view_plane_height * 0.5f);
		clip_plane_B		= EPlane3D(point, normalB);

		// 摄像机坐标系到透视坐标系变换矩阵, 经过矩阵变换之后需要除以w
		mPerspectiveToScreen = EMatrix44(view_dist,0,	0,	0,
										0,view_dist * aspect_ratio,	0, 0,
										0,			0,	1,	1,
										0,			0,	0,	0);
	}

	//--------------------------------------------------------------------------

	//void EFrustum::updateCamera()
	//{
	//	switch(camMode)
	//	{
	//	case CAMERA_MODEL_ELUA:
	//		{
	//			/** 欧拉角摄像机创建变换矩阵,需要这么做
	//			Mcam = mt(-1) * my(-1) * mx(-1) * mz(-1)
	//			即相机平移矩阵的逆矩阵 乘以 相机绕y,x,z轴的旋转矩阵的逆矩阵
	//			*/
	//			EMatrix44 mt_inv;
	//			GetTranslateMatrix44(mt_inv, -position.x, -position.y, -position.z);
	//			// direction各分量分别存储的是延各轴的旋转分量
	//			EMatrix44 mx_inv;
	//			GetRotateMatrix44X(mx_inv, -direction.x);
	//			EMatrix44 my_inv;
	//			GetRotateMatrix44Y(my_inv, -direction.y);
	//			EMatrix44 mz_inv;
	//			GetRotateMatrix44Z(mz_inv, -direction.z);

	//			mWorldToCamera = mt_inv * my_inv * mz_inv * mz_inv;
	//		}
	//		break;
	//	case CAMERA_MODEL_UVN:
	//		{
	//			EMatrix44 mt_inv;
	//			GetTranslateMatrix44(mt_inv, -position.x, -position.y, -position.z);
	//			camLook				= camTarget - position;

	//			camUp				= EVector4D::UNIT_Y;
	//			camRight			= camUp.crossProduct(camLook);
	//			camUp				= camLook.crossProduct(camRight);

	//			camLook.normalize();
	//			camRight.normalize();
	//			camUp.normalize();

	//			EMatrix44 mt_uvn(	camRight.x, camUp.x, camLook.x, 0,
	//								camRight.y, camUp.y, camLook.y, 0,
	//								camRight.z, camUp.z, camLook.z, 0,
	//								0			,0		, 0			,1);
	//			mWorldToCamera = mt_inv * mt_uvn;
	//		}
	//		break;
	//	}
	//}

	//--------------------------------------------------------------------------

}